﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

namespace Utility.Text
{
	public class TextBuilder
	{
		StringBuilder sb = new StringBuilder ();

		int _indent = 0;
		string _indentStr = "";
		public int IndentLevel
		{
			get => _indent;
			set
			{
				if (_indent != value)
				{
					_indent = value;
					_indentStr = "";
					for (int i = 0; i < value; i++)
					{
						_indentStr += Indenter;
					}
				}
			}
		}

		public string Indenter { get; set; } = "\t";

		public void Clear ()
		{
			sb.Clear ();
			IndentLevel = 0;
		}

		public override string ToString ()
		{
			return sb.ToString ();
		}

		public string Flush ()
		{
			string str = sb.ToString ();
			Clear ();
			return str;
		}

		public void AppendLine (string line)
		{
			sb.AppendLine (_indentStr + line);
		}

		public void BlankLine ()
		{
			sb.AppendLine ("");
		}
	}

	#region scopes
	public abstract class TextScope : IDisposable
	{
		protected TextBuilder builder;

		protected TextScope (TextBuilder builder)
		{
			this.builder = builder;
		}

		protected abstract void OnStart ();
		protected abstract void OnEnd ();

		public TextScope Start ()
		{
			OnStart ();
			return this;
		}

		public void End ()
		{
			OnEnd ();
		}

		void IDisposable.Dispose () => End ();
	}

	public class IndentScope : TextScope
	{
		int indent;
		int indentRecord;

		public IndentScope (TextBuilder builder, int indent = 1) : base (builder)
		{
			this.indent = indent;
			this.indentRecord = builder.IndentLevel;
		}

		protected override void OnStart ()
		{
			builder.IndentLevel += indent;
		}
		protected override void OnEnd ()
		{
			builder.IndentLevel = indentRecord;
		}
	}

	public class CurlyBraceScope : IndentScope
	{
		public CurlyBraceScope (TextBuilder builder) : base (builder, 1)
		{
		}

		protected override void OnStart ()
		{
			builder.AppendLine ("{");
			base.OnStart ();
		}

		protected override void OnEnd ()
		{
			base.OnEnd ();
			builder.AppendLine ("}");
		}
	}


	#endregion
}